#!/usr/bin/env node
/**
 * Phase3.5 实现验证脚本
 *
 * 目的: 在Phase3配置注册后,验证引用的文件是否实际存在
 * 作用: 防止"假设-验证"断层,确保Edit配置引用的面板文件真实存在
 *
 * 执行时机: Phase3完成后,Phase4执行前
 * 质量门控: 所有引用文件必须存在,缺失则生成gap report并触发Phase4修复
 */

const fs = require('fs');
const path = require('path');

const PROJECT_ROOT = path.resolve(__dirname, '..');

/**
 * 从Edit配置中提取自定义面板引用
 */
function extractCustomPanelReferences(componentCode) {
  const editFilePath = path.join(PROJECT_ROOT, 'src/components/editor/schema/edit/aiComponents.ts');

  if (!fs.existsSync(editFilePath)) {
    return { success: false, error: 'Edit配置文件不存在' };
  }

  const editContent = fs.readFileSync(editFilePath, 'utf-8');

  // 查找组件的Edit配置块
  const componentRegex = new RegExp(`${componentCode}:\\s*\\[([\\s\\S]*?)\\]`, 'm');
  const match = editContent.match(componentRegex);

  if (!match) {
    return { success: false, error: `未找到${componentCode}的Edit配置` };
  }

  const configBlock = match[1];
  const refs = [];

  // 提取slot引用 (如 { slot: 'renderCardStyle' })
  const slotRegex = /slot:\s*['"`]([^'"`]+)['"`]/g;
  let slotMatch;
  while ((slotMatch = slotRegex.exec(configBlock)) !== null) {
    refs.push({
      type: 'slot',
      slotName: slotMatch[1],
      expectedPattern: `render${slotMatch[1].replace('render', '')}/${componentCode}.tsx`
    });
  }

  // 提取直接引用的renderXXX面板
  const renderRegex = /belongTo:\s*['"`](render[A-Za-z]+)['"`]/g;
  let renderMatch;
  while ((renderMatch = renderRegex.exec(configBlock)) !== null) {
    const belongTo = renderMatch[1];
    refs.push({
      type: 'belongTo',
      panelName: belongTo,
      expectedPattern: `${belongTo}/render${componentCode}.tsx`
    });
  }

  return { success: true, refs };
}

/**
 * 解析面板引用路径为文件系统路径
 */
function resolveCustomPanelPath(ref, componentCode) {
  const baseDir = path.join(PROJECT_ROOT, 'src/components/editor/Right');

  if (ref.type === 'slot') {
    // slot引用: renderCardStyle -> Right/renderCardStyle/renderComponentName.tsx
    return path.join(baseDir, ref.slotName, `render${componentCode}.tsx`);
  } else if (ref.type === 'belongTo') {
    // belongTo引用: renderBasicInfo -> Right/renderBasicInfo/renderComponentName.tsx
    return path.join(baseDir, ref.panelName, `render${componentCode}.tsx`);
  }

  return null;
}

/**
 * 检查auxiliary面板对齐度
 */
function checkAuxiliaryAlignment(componentCode) {
  const phase1Dir = path.join(PROJECT_ROOT, `${componentCode}/phase1`);

  // 检查是否存在auxiliary数据
  const auxiliaryContentPath = path.join(phase1Dir, 'auxiliary/content/panel-structure.json');
  const auxiliaryStylePath = path.join(phase1Dir, 'auxiliary/style/panel-structure.json');

  const hasAuxiliary = fs.existsSync(auxiliaryContentPath) || fs.existsSync(auxiliaryStylePath);

  if (!hasAuxiliary) {
    return {
      available: false,
      message: '无auxiliary面板数据'
    };
  }

  const auxiliaryPanels = [];

  if (fs.existsSync(auxiliaryContentPath)) {
    auxiliaryPanels.push({
      type: 'content',
      path: auxiliaryContentPath,
      data: JSON.parse(fs.readFileSync(auxiliaryContentPath, 'utf-8'))
    });
  }

  if (fs.existsSync(auxiliaryStylePath)) {
    auxiliaryPanels.push({
      type: 'style',
      path: auxiliaryStylePath,
      data: JSON.parse(fs.readFileSync(auxiliaryStylePath, 'utf-8'))
    });
  }

  return {
    available: true,
    panels: auxiliaryPanels
  };
}

/**
 * 检查variant-specific面板逻辑
 */
function checkVariantSpecificLogic(filePath, componentCode) {
  if (!fs.existsSync(filePath)) {
    return { implemented: false, reason: '文件不存在' };
  }

  const content = fs.readFileSync(filePath, 'utf-8');

  // 检查是否有variant条件判断
  const hasDesignTemplateCheck = /designTemplate|designStyle/i.test(content);
  const hasConditionalReturn = /if\s*\([^)]*\)\s*{\s*return\s+null/i.test(content);
  const hasFormUseWatch = /Form\.useWatch/i.test(content);

  return {
    implemented: hasDesignTemplateCheck && (hasConditionalReturn || hasFormUseWatch),
    checks: {
      hasDesignTemplateCheck,
      hasConditionalReturn,
      hasFormUseWatch
    }
  };
}

/**
 * 主验证函数
 */
async function verifyImplementation(componentCode) {
  console.log(`\n=== Phase3.5 实现验证: ${componentCode} ===\n`);

  const report = {
    timestamp: new Date().toISOString(),
    componentCode,
    verification: {
      filesystemCheck: {},
      variantLogicCheck: {},
      auxiliaryAlignment: {}
    },
    gap: {
      missingPanels: [],
      missingVariantLogic: [],
      auxiliaryMismatches: []
    },
    recommendation: null
  };

  // Step 1: 提取自定义面板引用
  console.log('Step 1: 提取Edit配置中的自定义面板引用...');
  const extraction = extractCustomPanelReferences(componentCode);

  if (!extraction.success) {
    console.error(`错误: ${extraction.error}`);
    report.verification.filesystemCheck.status = 'error';
    report.verification.filesystemCheck.error = extraction.error;
    return report;
  }

  console.log(`发现 ${extraction.refs.length} 个面板引用\n`);

  // Step 2: 文件存在性检查
  console.log('Step 2: 验证引用文件是否存在...');
  const missingPanels = [];
  const existingPanels = [];

  for (const ref of extraction.refs) {
    const filePath = resolveCustomPanelPath(ref, componentCode);
    const exists = fs.existsSync(filePath);

    const result = {
      reference: ref,
      expectedPath: filePath,
      exists,
      referencedBy: 'Edit config'
    };

    if (exists) {
      existingPanels.push(result);
      console.log(`✅ ${path.relative(PROJECT_ROOT, filePath)}`);
    } else {
      missingPanels.push(result);
      console.log(`❌ ${path.relative(PROJECT_ROOT, filePath)} (缺失)`);
    }
  }

  report.verification.filesystemCheck = {
    status: missingPanels.length === 0 ? 'pass' : 'fail',
    totalRefs: extraction.refs.length,
    existingPanels: existingPanels.length,
    missingPanels: missingPanels.length,
    details: { existingPanels, missingPanels }
  };

  // Step 3: Variant-specific逻辑检查
  console.log('\nStep 3: 检查variant-specific逻辑实现...');
  const executionContext = path.join(PROJECT_ROOT, `${componentCode}/phase0/execution-context.json`);

  if (fs.existsSync(executionContext)) {
    const context = JSON.parse(fs.readFileSync(executionContext, 'utf-8'));
    const hasUIVariants = context?.figma?.hasUIVariants === true;

    if (hasUIVariants) {
      console.log('检测到UI变体需求,验证variant逻辑...');

      for (const panel of existingPanels) {
        const variantCheck = checkVariantSpecificLogic(panel.expectedPath, componentCode);

        if (!variantCheck.implemented) {
          report.gap.missingVariantLogic.push({
            filePath: panel.expectedPath,
            reason: variantCheck.reason,
            checks: variantCheck.checks
          });
          console.log(`⚠️  ${path.relative(PROJECT_ROOT, panel.expectedPath)}: 缺少variant条件逻辑`);
        } else {
          console.log(`✅ ${path.relative(PROJECT_ROOT, panel.expectedPath)}: variant逻辑已实现`);
        }
      }

      report.verification.variantLogicCheck = {
        status: report.gap.missingVariantLogic.length === 0 ? 'pass' : 'warning',
        hasUIVariants: true,
        checkedPanels: existingPanels.length,
        missingLogic: report.gap.missingVariantLogic.length
      };
    } else {
      report.verification.variantLogicCheck = {
        status: 'skip',
        hasUIVariants: false,
        reason: '组件无UI变体'
      };
      console.log('组件无UI变体,跳过variant逻辑检查');
    }
  }

  // Step 4: Auxiliary面板对齐检查
  console.log('\nStep 4: 检查Figma auxiliary面板对齐度...');
  const auxiliaryCheck = checkAuxiliaryAlignment(componentCode);

  if (auxiliaryCheck.available) {
    console.log(`发现 ${auxiliaryCheck.panels.length} 个auxiliary面板定义`);

    // 对比auxiliary定义与实际文件
    for (const auxPanel of auxiliaryCheck.panels) {
      const sections = auxPanel.data.sections || [];

      for (const section of sections) {
        // 检查section对应的面板文件是否存在
        const sectionName = section.title || section.name;
        console.log(`  检查 ${auxPanel.type} 面板 section: ${sectionName}`);

        // 简化检查:如果有任何missing panels,记录为mismatch
        if (missingPanels.length > 0) {
          report.gap.auxiliaryMismatches.push({
            auxiliaryType: auxPanel.type,
            sectionName,
            nodeId: auxPanel.data.nodeId,
            reason: '存在缺失的面板文件'
          });
        }
      }
    }

    report.verification.auxiliaryAlignment = {
      status: report.gap.auxiliaryMismatches.length === 0 ? 'pass' : 'warning',
      auxiliaryAvailable: true,
      panelsChecked: auxiliaryCheck.panels.length,
      mismatches: report.gap.auxiliaryMismatches.length
    };
  } else {
    report.verification.auxiliaryAlignment = {
      status: 'skip',
      auxiliaryAvailable: false,
      reason: auxiliaryCheck.message
    };
    console.log(auxiliaryCheck.message);
  }

  // Step 5: 生成建议
  console.log('\n=== 验证结果汇总 ===\n');

  report.gap.missingPanels = missingPanels;

  if (missingPanels.length > 0) {
    console.log(`❌ 发现 ${missingPanels.length} 个缺失的面板文件`);
    report.recommendation = {
      action: 'trigger_phase4_generation',
      reason: '存在Edit配置引用但文件系统缺失的面板',
      targetPhase: 'Phase4',
      missingCount: missingPanels.length
    };
  } else if (report.gap.missingVariantLogic.length > 0) {
    console.log(`⚠️  存在 ${report.gap.missingVariantLogic.length} 个面板缺少variant逻辑`);
    report.recommendation = {
      action: 'enhance_variant_logic',
      reason: '面板文件存在但缺少variant条件逻辑',
      targetPhase: 'Phase4',
      filesNeedingEnhancement: report.gap.missingVariantLogic.length
    };
  } else {
    console.log('✅ 所有验证通过,实现与配置完全对齐');
    report.recommendation = {
      action: 'skip_phase4',
      reason: '所有引用的面板文件存在且逻辑完整',
      targetPhase: 'Phase5'
    };
  }

  // 保存报告
  const outputPath = path.join(PROJECT_ROOT, `${componentCode}/phase3.5/implementation-verification-report.json`);
  const outputDir = path.dirname(outputPath);

  if (!fs.existsSync(outputDir)) {
    fs.mkdirSync(outputDir, { recursive: true });
  }

  fs.writeFileSync(outputPath, JSON.stringify(report, null, 2), 'utf-8');
  console.log(`\n报告已保存: ${path.relative(PROJECT_ROOT, outputPath)}`);

  return report;
}

// CLI执行
if (require.main === module) {
  const componentCode = process.argv[2];

  if (!componentCode) {
    console.error('用法: node scripts/phase3.5-implementation-verification.js <ComponentCode>');
    process.exit(1);
  }

  verifyImplementation(componentCode)
    .then(report => {
      const hasErrors = report.gap.missingPanels.length > 0;
      process.exit(hasErrors ? 1 : 0);
    })
    .catch(err => {
      console.error('执行失败:', err);
      process.exit(1);
    });
}

module.exports = { verifyImplementation };
